#!/usr/bin/env python
# coding=utf-8
# Created on 2015年6月25日
# author: ep@zmeng
import threading
import Queue
import json
import logging
import time
import tornado.web
import tornado.ioloop
from glogging import glogging_process_info, glogging_process_error, glogging_state_info

# demo_processes = {
#     'name1':    {
#             'processor':  'processor_func',
#             'cores': 3,
#             'pattern': 'xxxxx',
#     },
#     'name2':    {
#             'processor':  'processor_func',
#             'cores': 1,
#             'pattern': 'xxxxx',
#     },
# }


def simple_response(request=None, err_no=0, msg=''):
    request.write(json.dumps({
        "err_no": err_no,
        "msg": msg
    }))
    request.finish()


def success_response(request=None, response=''):
    response['err_no'] = 0
    request.write(json.dumps(response))
    request.finish()


def request_method_alert(request=None, method=''):
    if method == request.request.method:
        return True
    else:
        return False


class _MCommonHandler(tornado.web.RequestHandler):
    def initialize(self, serv=None, name='default'):
        self.serv = serv
        self.name = name

    @tornado.web.asynchronous
    def get(self):
        glogging_process_info("[%s] Got Get request, args[%s]" %
                              (self.name, self.request.arguments))
        self.serv.solve(self.name, self)

    @tornado.web.asynchronous
    def post(self):
        glogging_process_info("[%s] Got Post request, args[%s]" % (
            self.name, self.request.arguments))
        self.serv.solve(self.name, self)


class GLAPIServ(threading.Thread):
    def __init__(self, listen_ip=None, listen_port=None, processes=None, settings={}):
        super(GLAPIServ, self).__init__(name="GL API Serv Thread")
        if (not listen_ip or not listen_port or not processes):
            return None

        self.listen_ip = listen_ip
        self.listen_port = listen_port
        self.handlers = []
        self.settings = settings
        self.processes = processes
        for name in processes.keys():
            self.handlers.append((processes[name]['pattern'], _MCommonHandler, {'serv': self, 'name': name}))
            processes[name]['pq'] = Queue.Queue()

    def run(self):
        application = tornado.web.Application(self.handlers, **(self.settings))
        application.listen(self.listen_port, self.listen_ip)

        for name in self.processes.keys():
            for i in range(self.processes[name]['cores']):
                t = threading.Thread(target=self._base_web_handler, args=(name, i, ))
                t.start()

        tornado.ioloop.IOLoop.instance().start()

    def _base_web_handler(self, name, serial_id):
        glogging_state_info("Start [%s] processor.%d" % (name, serial_id))
        while True:
            try:
                request = self.processes[name]['pq'].get(True, 60)
                self.processes[name]['processor'](request)
            except Queue.Empty:
                continue
            except Exception, e:
                glogging_process_error("WebServer  Main handler Got [%s]" % (str(e)))
                simple_response(request, 0, "internal server error")

    def solve(self, name, request):
        self.processes[name]['pq'].put(request, False, 0.1)
